<?php
namespace App\Http\Controllers;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class ScreenController extends Controller implements MessageComponentInterface{
    private $connections = [];
    private $resources = [];
    private $redis;

    public function __construct() {
        // if (!$this->redis){
        //     $rs = app('redis.connection');
        //     $this->redis = $rs;
        // }
    }
    
     /**
     * When a new connection is opened it will be passed to this method
     * @param  ConnectionInterface $conn The socket/connection that just connected to your application
     * @throws \Exception
     */
    function onOpen(ConnectionInterface $conn){
        
        $uid = hashid();
        $this->connections[$conn->resourceId] = compact('conn') + ['user_id' => $uid];
        $this->resources[$uid] = $conn->resourceId;
        $data = ['uid' => $uid];
        $conn->send(json_encode($data));
        
    }
    
     /**
     * This is called before or after a socket is closed (depends on how it's closed).  SendMessage to $conn will not result in an error if it has already been closed.
     * @param  ConnectionInterface $conn The socket/connection that is closing/closed
     * @throws \Exception
     */
    function onClose(ConnectionInterface $conn){
        $disconnectedId = $conn->resourceId;
        unset($this->connections[$disconnectedId]);
        foreach($this->connections as &$connection)
            $connection['conn']->send(json_encode([
                'offline_user' => $disconnectedId,
                'from_user_id' => 'server control',
                'from_resource_id' => null
            ]));
    }
    
     /**
     * If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown,
     * the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method
     * @param  ConnectionInterface $conn
     * @param  \Exception $e
     * @throws \Exception
     */
    function onError(ConnectionInterface $conn, \Exception $e){
        $userId = $this->connections[$conn->resourceId]['user_id'];
        echo "An error has occurred with user $userId: {$e->getMessage()}\n";
        unset($this->connections[$conn->resourceId]);
        $conn->close();
    }
    
     /**
     * Triggered when a client sends data through the socket
     * @param  \Ratchet\ConnectionInterface $conn The socket/connection that sent the message to your application
     * @param  string $msg The message received
     * @throws \Exception
     */
    function onMessage(ConnectionInterface $conn, $msg){
        if (empty(trim($msg))) return;
        
            $fromUserId = $this->connections[$conn->resourceId]['user_id'];
            $data = json_decode($msg, true);
            if (isset($data['source_id'])){
                $source_id = $data['source_id'];
                $room_id = 'TargetScreenRoom:'.$source_id;
                if (isset($data['uid'])){
                    // 存在 uid 首次需要注册
                    // 当前 uid 所属的列表
                    // fd 归属的房间号
                    $this->screenRoom[$conn->resourceId] = $room_id;
                    // 房间内成员
                    array_push($this->members[$room_id], $conn->resourceId);
                    echo "Uid: {$data['uid']} , Rid: {$conn->resourceId}  Connecting".PHP_EOL;
                }else{
                    // 获取所有连接名
                    $members = $this->members[$room_id];
                    
                    foreach ($members as $resourceId){
                        $conn = &$this->connections[$resourceId];
                        $conn->send($msg);
                    }
                }
            }
        
    }
}
